package com.tanhua.sso.server.service;

import cn.hutool.Hutool;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.tanhua.api.*;
import com.tanhua.autoconfig.tmplate.OssTemplate;
import com.tanhua.config.UserHolder;
import com.tanhua.exceptionhander.CustomException;
import com.tanhua.result.Result;
import com.tanhua.sso.pojo.*;
import com.tanhua.sso.utils.CommentType;
import com.tanhua.sso.vo.MovementsVo;
import com.tanhua.sso.vo.NearbyUserVo;
import com.tanhua.sso.vo.TodayBest;
import com.tanhua.sso.vo.UserInfoVo;
import com.tanhua.util.Constants;
import com.tanhua.util.IdWorker;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class MovementService {
    //图片上传
    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private UserInfoService userInfoService;

    @DubboReference
    private MovementsService movementsService;

    @DubboReference
    private CommentsServiceApi commentsServiceApi;

    //redis
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @DubboReference
    private VisitorsServiceApi visitorsServiceApi;

    @DubboReference
    private RecommendUserService recommendUserService;

    @Autowired
    private AppMqMessageService appMqMessageService;

    @Autowired
    private AppUserFreezeService appUserFreezeService;

    //发布动态
    public void publish(Movement movement, MultipartFile [] imageContent,String location) throws IOException {
        appUserFreezeService.checkUserStatus("3",UserHolder.getUserId());
        //mq发送信息
        appMqMessageService.sendLogService(UserHolder.getUserId(),"0201","movement",null);
        if (ObjectUtil.isEmpty(movement.getTextContent())){
            throw new CustomException("不能发布空的类容");
        }
        //存储路径集合
        List<String> uriList=new ArrayList<>();
        //图片上传到阿里云,并获取图片路径
        for (MultipartFile multipartFile : imageContent) {

                String upload = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                uriList.add(upload);

        }
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //设置当前时间
        movement.setCreated(System.currentTimeMillis());
        //设置当前用户id
        movement.setUserId(userId);
        //设置图片路径
        movement.setMedias(uriList);
        movement.setLocationName(location);

        //发布动态
        movementsService.publish(movement);
    }

    //查看个人动态
    public Result all(Integer page, Integer pagesize, Long userid) {

        //mq发送信息
        appMqMessageService.sendLogService(UserHolder.getUserId(),"0202","movement",null);
        //动态数据
       List<Movement> movementList= movementsService.myMovement(page,pagesize,userid);
       //判断是否存在动态
       if (movementList==null){
           throw new CustomException("暂无动态");
       }
       //获取总条数
        int count = movementList.size();
       //获取多少页
        Integer pages=(count/pagesize)+1;
        //当前用户信息
        UserInfo userInfo = userInfoService.selectUser(userid);
        //添加封装动态信息
        List<MovementsVo> movementsVoList=new ArrayList<>();
        for (Movement movement : movementList) {
            MovementsVo vo = MovementsVo.init(userInfo, movement);
            movementsVoList.add(vo);
        }
        //分页查询数据
        return new Result(count,pagesize,pages,page,movementsVoList);
    }

    /*
    * 查看好友动态*/
    public Result friendAll(Integer page, Integer pagesize) {
        //mq发送信息
        appMqMessageService.sendLogService(UserHolder.getUserId(),"0201","movement",null);
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //查看好友动态
        List<Movement> movementList=movementsService.friendMovement(page,pagesize,userId);
        //判断集合是否存在
        if (ObjectUtil.isEmpty(movementList)){
            throw new CustomException("动态不存在");
        }
        return getResult(page, pagesize, movementList);
    }

    //封装分页查询
    private Result getResult(Integer page, Integer pagesize, List<Movement> movementList) {
        //获取
        List<MovementsVo> movementsVoList=new ArrayList<>();
        for (Movement movement : movementList) {
            Long movementUserId = movement.getUserId();
            //获取发送者信息
            UserInfo userInfo = userInfoService.selectUser(movementUserId);
            //组装封装
            MovementsVo vo = MovementsVo.init(userInfo, movement);
            //添加到集合里
            movementsVoList.add(vo);

        }
        //获取总条数
        int count = movementList.size();
        //获取多少页
        Integer pages=(count/ pagesize)+1;
        return new Result(count, pagesize,pages, page,movementsVoList);
    }


    /*查看推荐动态,推荐动态pid,计算出来存储在redis里,优先从redis里
    * 取数据,若redis中推荐动态刷完,则取其他动态*/

    public Result recommend(Integer page, Integer pagesize) {
        //mq发送信息
        appMqMessageService.sendLogService(UserHolder.getUserId(),"0201","movement",null);
        List<Movement> movementList=new ArrayList<>();
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //从redis里查询推荐的pid
        //获取redis的key
        String key=Constants.MOVEMENTS_RECOMMEND+userId;
        //从redis取出pid;
        String pidString = redisTemplate.opsForValue().get(key);
        //value是否为空
        if (StrUtil.isEmpty(pidString)){
            //查看随机动态,页码用不到
            movementList=movementsService.randomMovement(pagesize);
        }else {
            //value存在,去通过pid查询推荐动态
            //切割pid字符串
            String[] pidArr = pidString.split(",");
            //如果分页查询查询数据,不够则查询随机动态
            if ((page-1)*pagesize>=pidArr.length){
                movementList=movementsService.randomMovement(pagesize);

            }else {
                //通过页码和每页查询条数,计算出要查询动态pid
                List<Long> collectPid = Arrays.stream(pidArr).skip((page - 1) * pagesize).limit(pagesize).map(s -> Convert.toLong(s)).collect(Collectors.toList());
                //通过pid集合查询动态
                movementList=movementsService.findBypids(collectPid);
            }
        }

        Result result = getResult(page, pagesize, movementList);
        return result;
    }


    /*查看个人动态*/
    public MovementsVo getMovementByid(String movementId) {
        //mq发送信息
        appMqMessageService.sendLogService(UserHolder.getUserId(),"0201","movement",movementId);
        //个人动态
        Movement movement=movementsService.getMovementByid(movementId);
        Long userId = movement.getUserId();
        //用户信息
        UserInfo userInfo = userInfoService.selectUser(userId);
        //封装movementvo
        MovementsVo movementsVo = MovementsVo.init(userInfo, movement);
        return movementsVo;
    }

    /*点赞*/
    public Integer like(ObjectId id) {
        //mq发送信息
        appMqMessageService.sendLogService(UserHolder.getUserId(),"0203","movement",id.toHexString());
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //判断是否点赞
        boolean flag=movementsService.islike(id,userId);
        if (flag){
            throw new CustomException("已经点过赞了");
        }
        Comment comment=new Comment();
        //封装类型
        comment.setCommentType(CommentType.LIKE.getType());
        //设置动态id
        comment.setPublishId(id);
        //设置创建时间
        comment.setCreated(System.currentTimeMillis());
        //点赞人id
        comment.setUserId(userId);
        //返回点赞数
        Integer count = commentsServiceApi.save(comment);
        return count;
    }

    /*取消点赞*/
    public Integer disLike(ObjectId id) {
        //mq发送信息
        appMqMessageService.sendLogService(UserHolder.getUserId(),"0206","movement",id.toHexString());
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //判断是否点赞
        boolean flag=movementsService.islike(id,userId);
        if (!flag){
            throw new CustomException("你还没有点赞哦");
        }
        //取消点赞并返回点赞数量
        Integer count=movementsService.disLike(id,userId);

        return count;
    }

    /*喜欢*/
    public Integer love(ObjectId id) {
        //mq发送信息
        appMqMessageService.sendLogService(UserHolder.getUserId(),"0204","movement",id.toHexString());
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //查看是否已经喜欢
        boolean flag=movementsService.isLove(id,userId);
        if (flag){
            throw new CustomException("已经喜欢过了");
        }
        Comment comment=new Comment();
        //封装对象
        comment.setCommentType(CommentType.LOVE.getType());
        comment.setCreated(System.currentTimeMillis());
        comment.setUserId(userId);
        comment.setPublishId(id);
        Integer count = commentsServiceApi.save(comment);
        return count;
    }

    /*取消喜欢*/
    public Integer unLove(ObjectId id) {
        //mq发送信息
        appMqMessageService.sendLogService(UserHolder.getUserId(),"0207","movement",id.toHexString());
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //查看是否已经喜欢
        boolean flag=movementsService.isLove(id,userId);
        if (!flag){
            throw new CustomException("还没有点击喜欢,快去给小姐姐点个小红心吧");
        }
        Integer count=movementsService.unLove(id,userId);
        return count;
    }


    //谁看过我
    public List<TodayBest> selectVisitors() {
        List<TodayBest> todayBestList=new ArrayList<>();
        List<Visitors> visitorsList=new ArrayList<>();
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //获取当前时间,存入redis中
        long timeMillis = System.currentTimeMillis();
        //查看redis是否查看记录
        String time = redisTemplate.opsForValue().get(Constants.VISITORS_TIME + userId);
        if (ObjectUtil.isEmpty(time)){
            redisTemplate.opsForValue().set(Constants.VISITORS_TIME+userId,Convert.toStr(timeMillis));
            //
            //第一次查看来访
           visitorsList=visitorsServiceApi.selectVisitors(userId,timeMillis);
            for (Visitors visitors : visitorsList) {
                TodayBest todayBest=new TodayBest();
                RecommendUser recommendUser = recommendUserService.selectByid(visitors.getVisitorUserId());
                //获取userinfo信息
                UserInfo userInfo=userInfoService.selectUser(visitors.getVisitorUserId());
                //切割tags
                String[] tags = userInfo.getTags().split(",");
                BeanUtils.copyProperties(userInfo,todayBest,"tags");
                //身份
                todayBest.setTags(tags);
                //缘分值
                todayBest.setFateValue(recommendUser.getScore().longValue());
                todayBestList.add(todayBest);
            }
           return todayBestList;
        }
        //获取之前存储的数据
        String oldTime = redisTemplate.opsForValue().get(Constants.VISITORS_TIME + userId);
        //修改redis中的时间
        redisTemplate.opsForValue().set(Constants.VISITORS_TIME+userId,Convert.toStr(timeMillis));
        //再次查看
        visitorsList=visitorsServiceApi.selectVisitor(userId,Convert.toLong(oldTime));
        for (Visitors visitors : visitorsList) {
            TodayBest todayBest=new TodayBest();
            RecommendUser recommendUser = recommendUserService.selectByid(visitors.getVisitorUserId());
            //获取userinfo信息
            UserInfo userInfo=userInfoService.selectUser(visitors.getVisitorUserId());
            //切割tags
            String[] tags = userInfo.getTags().split(",");
            BeanUtils.copyProperties(userInfo,todayBest,"tags");
            //身份
            todayBest.setTags(tags);
            //缘分值
            todayBest.setFateValue(recommendUser.getScore().longValue());
            todayBestList.add(todayBest);
        }
        return todayBestList;
    }
}
